Pular para o conteúdo principal

Arquitetura do microservice em Node

Camadas

Usamos uma arquitetura em camadas beaseado no conceito de arquitetura limpa e arquitetura hexagonal, onde cada camada tem uma responsabilidade bem definida. Esses padrões arquiteturais visam a separação de responsabilidades, tornando o código mais limpo e fácil de manter.

Segue abaixo as principais camadas da arquitetura:

Atualizado em 25/07/2024.

Para editar, acesse: https://drive.google.com/file/d/12XAgGmaX83WZWCd0cn82wKAb0nvq_7d5/view?usp=sharing

Conforme, pode-se observar no diagrama acima, temos 4 camadas principais e dois tipos de modelos para representação de dados:

Camadas principais

  • Controllers: São responsáveis por receber as requisições HTTP, chamar os serviços necessários e retornar a resposta HTTP. Geralmente, os controllers estão na camada de entrada da aplicação.
  • Services: São responsáveis por implementar a lógica de negócio da aplicação. Eles chamam os providers (interaces) para acessar os dados necessários e executar certas lógicas.
  • Providers (Interfaces): São interfaces que especificam funções de acesso a dados, acesso a bibliotecas e acesso a serviços externos. Eles são responsáveis por acessar o banco de dados, chamar APIs externas, etc.
  • Providers (Implementações): São implementações concretas das interfaces de providers. Eles são responsáveis por acessar o banco de dados, chamar APIs externas, etc.

Modelos de representação de dados

  • DTOs: Data Transfer Objects, são objetos que representam os dados que são transferidos entre as camadas da aplicação. São objetos simples, que não possuem lógica de negócio. Geralmente estão na camada do controller.
  • Entidades: São objetos que representam as entidades do domínio da aplicação. São objetos que podem possuir lógica de negócio.

Estrutura de pastas e arquivos

.
├── Dockerfile
├── coverage
├── dist
├── docker-compose.integration-test.yaml
├── docker-compose.local.yaml
├── eslint.config.mjs
├── nest-cli.json
├── node_modules
├── package.json
├── pnpm-lock.yaml
├── prisma
│   ├── migrations
│   │   ├── 20240724151227_basic_models_setup
│   │   │   └── migration.sql
│   │   └── migration_lock.toml
│   ├── schema.prisma
│   └── seed
│   ├── populate_all.ts
│   ├── populate_bank_connectors.ts
│   ├── populate_bank_transaction_category_guesser_models.ts
│   ├── populate_bank_transaction_indicators.ts
│   ├── populate_bank_transaction_legal_nature_guesser_models.ts
│   ├── populate_bank_transaction_model_category_tree.ts
│   ├── populate_bank_transaction_model_category_tree_other_business_v1.ts
│   └── populate_bank_transaction_model_category_tree_personal_v1.ts
├── public
│   ├── 404.html
│   └── index.html
├── scripts
│   └── setup_integration_test_db.sh
├── src
│   ├── api-page-response.decorator.ts
│   ├── app-exceptions.filter.ts
│   ├── app.dto.ts
│   ├── app.module.ts
│   ├── bank
│   │   ├── bank-accounts
│   │   │   ├── bank-accounts.controller.ts
│   │   │   ├── bank-accounts.module.ts
│   │   │   ├── bank-accounts.provider.ts
│   │   │   ├── bank-accounts.service.ts
│   │   │   ├── dtos
│   │   │   │   └── create-or-update-bank-account-request.dto.ts
│   │   │   ├── entities
│   │   │   │   ├── bank-account.entity.ts
│   │   │   │   ├── bank-accounts-balance-report.entity.ts
│   │   │   │   ├── create-or-update-bank-account-request.entity.ts
│   │   │   │   ├── list-bank-accounts-by-bank-connection-id-request.entity.ts
│   │   │   │   ├── list-bank-accounts-by-workspace-id-request.entity.ts
│   │   │   │   └── partial-update-bank-account-request.entity.ts
│   │   │   └── prisma-bank-accounts.provider.ts
│   │   └── bank-connections
│   │      ├── bank-connections.controller.ts
│   │      ├── bank-connections.module.ts
│   │      ├── bank-connections.provider.ts
│   │      ├── bank-connections.service.ts
│   │      ├── dtos
│   │      │   └── create-or-update-bank-connection-request.dto.ts
│   │      ├── entities
│   │      │   ├── bank-connection.entity.ts
│   │      │   ├── create-or-update-bank-connection-request.entity.ts
│   │      │   ├── list-bank-connections-request.entity.ts
│   │      │   └── partial-update-bank-connection-request.entity.ts
│   │      └── prisma-bank-connections.provider.ts
│   ├── base.controller.ts
│   ├── base.provider.ts
│   ├── base.service.ts
│   ├── communication
│   │   ├── email
│   │   │   ├── email.enums.ts
│   │   │   ├── email.module.ts
│   │   │   ├── email.provider.ts
│   │   │   ├── sendgrid-email.provider.ts
│   │   │   └── templates
│   │   │   └── email-verification-code-for-sign-up.template.ejs
│   │   ├── message-tokens
│   │   │   ├── dtos
│   │   │   │   └── create-or-update-message-token-request.dto.ts
│   │   │   ├── entities
│   │   │   │   ├── create-or-update-message-token-request.entity.ts
│   │   │   │   └── message-token.entity.ts
│   │   │   ├── message-tokens.controller.ts
│   │   │   ├── message-tokens.module.ts
│   │   │   ├── message-tokens.provider.ts
│   │   │   ├── message-tokens.service.ts
│   │   │   └── prisma-message-tokens.provider.ts
│   │   └── phone
│   │   ├── phone.module.ts
│   │   ├── phone.provider.ts
│   │   └── twillio-phone.provider.ts
│   ├── config
│   │   ├── configuration.ts
│   │   ├── development.configuration.ts
│   │   ├── integration-test.configuration.ts
│   │   ├── local.configuration.ts
│   │   ├── production.configuration.ts
│   │   └── staging.configuration.ts
│   ├── fields.ts
│   ├── hash
│   │   ├── argon-hash.provider.ts
│   │   ├── hash.module.ts
│   │   └── hash.provider.ts
│   ├── iam
│   ├── logger
│   │   ├── logger.module.ts
│   │   └── pino-logger.ts
│   ├── main.ts
│   ├── mobile-app-bff
│   ├── page-request.entity.ts
│   ├── page-response.entity.ts
│   ├── pluggy
│   ├── prisma
│   │   ├── prisma.module.ts
│   │   └── prisma.provider.ts
│   ├── queue
│   │   ├── gcp-cloud-tasks-queue.provider.ts
│   │   ├── prisma-queue.provider.ts
│   │   ├── queue.enums.ts
│   │   ├── queue.module.ts
│   │   └── queue.provider.ts
│   ├── random
│   │   ├── default-random.provider.ts
│   │   ├── random.module.ts
│   │   └── random.provider.ts
│   ├── reports
│   │   ├── entities
│   │   │   ├── cards-cash-flow-report.entity.ts
│   │   │   ├── cash-flow-by-category-report.entity.ts
│   │   │   ├── cash-flow-report.entity.ts
│   │   │   ├── financial-statement-report.entity.ts
│   │   │   └── indicator.entity.ts
│   │   ├── prisma-reports.provider.ts
│   │   ├── reports.controller.ts
│   │   ├── reports.module.ts
│   │   ├── reports.provider.ts
│   │   └── reports.service.ts
│   ├── setup.ts
│   ├── utils.ts
│   └── worker-io.guard.ts
├── swagger-generator-cli.ts
├── test
│   ├── app.fixture.ts
│   ├── bank
│   │   ├── bank-accounts
│   │   │   ├── activate.integration.test.ts
│   │   │   ├── create-or-update.integration.test.ts
│   │   │   ├── disable.integration.test.ts
│   │   │   ├── get-by-id.integration.test.ts
│   │   │   ├── list-by-bank-connection-id.integration.test.ts
│   │   │   └── list-by-workspace-id.integration.test.ts
│   │   ├── bank-connections
│   │   │   ├── activate.integration.test.ts
│   │   │   ├── create-or-update.integration.test.ts
│   │   │   ├── disable.integration.test.ts
│   │   │   ├── get-by-id.integration.test.ts
│   │   │   └── list.integration.test.ts
│   │   ├── bank-transaction-categories
│   │   │   └── list.integration.test.ts
│   │   ├── bank-transaction-tags
│   │   │   ├── create.integration.test.ts
│   │   │   └── list.integration.test.ts
│   │   └── bank-transactions
│   │   ├── create-or-update-in-bulk.integration.test.ts
│   │   ├── get-by-id.integration.test.ts
│   │   ├── get-by-provider.integration.test.ts
│   │   ├── list-most-recent.integration.test.ts
│   │   ├── list-not-verified.integration.test.ts
│   │   ├── list-verified-by-me.integration.test.ts
│   │   ├── list.integration.test.ts
│   │   └── partial-update.integration.test.ts
│   ├── communication
│   │   └── message-tokens
│   │   ├── create-or-update.integration.test.ts
│   │   └── list-by-worksapce-id.integration.test.ts
│   ├── global-setup-integration-tests.ts
│   ├── iam
│   │   ├── auth
│   │   │   ├── generate-and-send-email-verification-code.integration.test.ts
│   │   │   ├── generate-and-send-phone-verification-code.integration.test.ts
│   │   │   ├── generate-email-in-use-report.integration.test.ts
│   │   │   ├── generate-phone-in-use-report.integration.test.ts
│   │   │   ├── get-me.integration.test.ts
│   │   │   ├── refresh.integration.test.ts
│   │   │   ├── sign-in-with-email.integration.test.ts
│   │   │   ├── sign-up-with-email.integration.test.ts
│   │   │   ├── verify-email-verification-code.integration.test.ts
│   │   │   └── verify-phone-verification-code.integration.test.ts
│   │   ├── profiles
│   │   │   ├── create.integration.test.ts
│   │   │   ├── get-my.integration.test.ts
│   │   │   └── partial-update.integration.test.ts
│   │   └── workspaces
│   │   ├── create.integration.test.ts
│   │   ├── get-by-id.integration.test.ts
│   │   ├── list-my.integration.test.ts
│   │   └── partial-update.integration.test.ts
│   ├── instance-setup-integration-test.ts
│   └── pluggy
│   ├── create-connect-token.integration.test.ts
│   └── webhook.integration.test.ts
├── tsconfig.build.json
├── tsconfig.json
├── ui-debug.log
├── vitest.integration.config.ts
└── website

Acima, temos um exemplo de estrutura de pastas e arquivos de um microservice em Node (core-api). A estrutura acima é baseada no NestJS, um framework para NodeJS que facilita a criação de APIs REST.

Segue a descrição de algumas pastas e arquivos:

  • Dockerfile: Arquivo de configuração do Docker, usado para criar a imagem do microservice.
  • dist: Pasta onde ficam os arquivos transpilados do TypeScript.
  • prisma: Pasta onde ficam os arquivos de configuração do Prisma, um ORM usado para acessar o banco de dados.
  • src: Pasta onde ficam os arquivos de código-fonte do microservice.
  • test: Pasta onde ficam os arquivos de testes do microservice.
  • tsconfig.json: Arquivo de configuração do TypeScript.
  • website: Pasta onde ficam os arquivos do site de documentação do microservice (docusaurus).

Dentro da pasta src, temos algumas pastas e arquivos:

  • api-page-response.decorator.ts: Decorator usado para padronizar a resposta das APIs.
  • app-exceptions.filter.ts: Filtro usado para tratar exceções globais.
  • app.module.ts: Módulo principal da aplicação.
  • bank: Pasta onde ficam os arquivos relacionados ao módulo de bancos.
  • communication: Pasta onde ficam os arquivos relacionados ao módulo de comunicação.
  • config: Pasta onde ficam os arquivos de configuração da aplicação.
  • logger: Pasta onde ficam os arquivos relacionados ao logger da aplicação.
  • prisma: Pasta onde ficam os arquivos relacionados ao Prisma.
  • queue: Pasta onde ficam os arquivos relacionados à fila de mensagens.
  • reports: Pasta onde ficam os arquivos relacionados aos relatórios da aplicação.

O módulo bank contém internamente outros módulos, como bank-accounts, bank-connections etc. Cada módulo contém os arquivos de controller, service, provider, entidade, DTO, etc. Futuramente podemos extrair esses módulos de bank para um microservice separado.